#!/usr/bin/python

import sys
from operator import attrgetter
from optparse import OptionParser

import boto
from boto.ec2 import regions


HEADERS = {
    'ID': {'get': attrgetter('id'), 'length':15},
    'Zone': {'get': attrgetter('placement'), 'length':15},
    'Groups': {'get': attrgetter('groups'), 'length':30},
    'Hostname': {'get': attrgetter('public_dns_name'), 'length':50},
    'State': {'get': attrgetter('state'), 'length':15},
    'Image': {'get': attrgetter('image_id'), 'length':15},
    'Type': {'get': attrgetter('instance_type'), 'length':15},
    'IP': {'get': attrgetter('ip_address'), 'length':16},
    'PrivateIP': {'get': attrgetter('private_ip_address'), 'length':16},
    'Key': {'get': attrgetter('key_name'), 'length':25},
    'T:': {'length': 30},
}

def get_column(name, instance=None):
    if name.startswith('T:'):
        _, tag = name.split(':', 1)
        return instance.tags.get(tag, '')
    return HEADERS[name]['get'](instance)


def main():
    parser = OptionParser()
    parser.add_option("-r", "--region", help="Region (default us-east-1)", dest="region", default="us-east-1")
    parser.add_option("-H", "--headers", help="Set headers (use 'T:tagname' for including tags)", default=None, action="store", dest="headers", metavar="ID,Zone,Groups,Hostname,State,T:Name")
    (options, args) = parser.parse_args()

    # Connect the region
    for r in regions():
        if r.name == options.region:
            region = r
            break
    else:
        print "Region %s not found." % options.region
        sys.exit(1)
    ec2 = boto.connect_ec2(region=region)

    # Read headers
    if options.headers:
        headers = tuple(options.headers.split(','))
    else:
        headers = ("ID", 'Zone', "Groups", "Hostname")

    # Create format string
    format_string = ""
    for h in headers:
        if h.startswith('T:'):
            format_string += "%%-%ds" % HEADERS['T:']['length']
        else:
            format_string += "%%-%ds" % HEADERS[h]['length']


    # List and print
    print format_string % headers
    print "-" * len(format_string % headers)
    for r in ec2.get_all_instances():
        groups = [g.name for g in r.groups]
        for i in r.instances:
            i.groups = ','.join(groups)
            print format_string % tuple(get_column(h, i) for h in headers)

if __name__ == "__main__":
    main()
